﻿Imports System.ComponentModel
Imports System.Collections.ObjectModel
Imports System.Windows.Forms

Namespace Cues
	<Serializable> Public Class Stack
		Inherits CueBase
#Region "Inherited Stuff"

		''' <summary>
		''' Sets the cue to standby.
		''' </summary>
		''' <remarks></remarks>
		Public Overrides Sub Standby()
			MyBase.Status = CueStatus.Standby
		End Sub


		''' <summary>
		''' Starts the cue by calling the "Go" action on the Stack's cuelist.
		''' </summary>
		''' <remarks></remarks>
		Public Overrides Sub Start()
			'For Each cue In CueList
			'	If cue.Status = CueStatus.Active Then
			'		Return
			'	End If
			'Next
			If CueList.Where(Function(c) c.Status = CueStatus.Active).Count > 0 Then
				Return
			ElseIf CueList.Where(Function(c) c.Status = CueStatus.Cued).Count > 0 Then
				CueList.Go()
			Else
				CueList.Item(0).Status = CueStatus.Cued
				CueList.Go()
			End If
			'If TransportAction = CueActions.Pause AndAlso ActionDelay > 0 Then
			'	TransportActionTimer = New Timers.Timer(ActionDelay)
			'	TransportActionTimer.AutoReset = False
			'	TransportActionTimer.Start()
			'ElseIf TransportAction = CueActions.Pause AndAlso ActionDelay = 0 Then
			'	RaiseStartTransportAction(Me, New EventArgs)
			'End If
			My.Application.Show.Console.SendMessage("Stack Cue: " & FullNumber & " tried to play.")
		End Sub

		''' <summary>
		''' Stops every active cue in the list.
		''' </summary>
		''' <param name="UseFade"></param>
		''' <remarks></remarks>
		Public Overrides Async Sub [Stop](Optional UseFade As Boolean = True)
			'For Each c As Cues.CueBase In CueList.Where(Function(d) d.Status = CueStatus.Active)
			'	c.Stop(UseFade)
			'Next
			'For Each c As Cues.Audio In CueList.OfType(Of Cues.Audio).Where(Function(d) d.Player IsNot Nothing AndAlso d.Player.IsPlaying)
			'	c.Stop(UseFade)
			'Next
			'For Each c As Cues.CueBase In CueList.Where(Function(d) d.Status = CueStatus.Cued)
			'	c.Standby()
			'Next
			Await CueList.StopAllCues(UseFade)
			MyBase.RaiseCueStopped(Me, True)
			Status = CueStatus.Standby
			Try
				My.Application.Show.Console.SendMessage("Stack Cue: " & FullNumber & " tried to stop.")
			Catch
			End Try
		End Sub

		''' <summary>
		''' Pauses every active cue in the list.
		''' </summary>
		''' <remarks></remarks>
		Public Sub Pause()
			For Each cue In CueList.Where(Function(c)
													   Return c.GetType Is GetType(Cues.Audio) AndAlso c.Status = CueStatus.Active
												   End Function)
				CType(cue, Cues.Audio).Pause()
			Next
			My.Application.Show.Console.SendMessage("Stack Cue: " & FullNumber & " tried to pause.")
		End Sub

		''' <summary>
		''' Returns "Stack Cue" if called.
		''' </summary>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Overrides Function ToString() As String
			Return "Stack Cue"
		End Function

		''' <summary>
		''' Creates a new StackCue, with a parent cue.
		''' </summary>
		''' <param name="ParentCueNumber">A number that represent's this cue's parent cue.</param>
		''' <remarks></remarks>
		Public Sub New(ParentCueNumber As String)
			MyBase.New(ParentCueNumber)
		End Sub

		''' <summary>
		''' Creates a new StackCue.
		''' </summary>
		''' <remarks></remarks>
		Public Sub New()
			MyBase.New()
		End Sub

#End Region

#Region "Private"

		''' <summary>
		''' When a property is changed checks to see if actions need to be taken.
		''' </summary>
		''' <remarks></remarks>
		Private Sub CheckCueChanges(sender As Object, e As PropertyChangedEventArgs) Handles MyBase.PropertyChanged
			If e.PropertyName = "Number" Then
				For Each c In CueList
					c.ParentCue = Number
				Next
			End If
		End Sub

		''' <summary>
		''' Raised when a property is changed. Passes the property change event on from the Stack Cue.
		''' </summary>
		''' <remarks></remarks>
		Private Sub ACueChanged(sender As Object, e As PropertyChangedEventArgs)
			RaisePropertyChanged(e.PropertyName)
		End Sub

#End Region

#Region "Properties"

		''' <summary>
		''' Represents the CueList Property.
		''' </summary>
		''' <remarks></remarks>
		Private CueListProperty As New Collections.CueList()
		''' <summary>
		''' The list of cue's in the StackCue.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property CueList As Collections.CueList
			Get
				Return CueListProperty
			End Get
			Set(value As Collections.CueList)
				If CueListProperty IsNot value Then
					CueListProperty = value
					RaisePropertyChanged("CueList")
				End If
			End Set
		End Property

#End Region

#Region "Public Functions"

		''' <summary>
		''' Adds a cue to the cue list.
		''' </summary>
		''' <param name="Cue">The cue to add to the list.</param>
		''' <remarks></remarks>
		Public Sub AddCue(Cue As Cues.CueBase)
			Try
				If CueList.Count > 0 Then
					Cue.Number = Math.Floor(CueList.Item(CueList.Count - 1).Number + 1)
				Else
					Cue.Number = 1
				End If
				CueList.Add(Cue)
				AddHandler Cue.PropertyChanged, AddressOf ACueChanged
				RaisePropertyChanged("CueList")
			Catch ex As Exception
				My.Application.Show.Console.SendMessage("There was a problem add a cue to the cue stack.", ex)
			End Try
		End Sub

		''' <summary>
		''' Removes a cue from the cue list, by number.
		''' </summary>
		''' <param name="CueNumber">The number of the cue to remove from the cue list.</param>
		''' <remarks></remarks>
		Public Sub RemoveCue(CueNumber As Double)
			Try
				Dim cue As Cues.CueBase = CueList.Where(Function(c) c.Number = CueNumber)(0)
				Try
					RemoveHandler cue.PropertyChanged, AddressOf ACueChanged
				Catch
				End Try
				CueList.Remove(cue)
				'CueList.Remove(CueList.Where(Function(c) c.Number = CueNumber))
				RaisePropertyChanged("CueList")
			Catch ex As Exception
				My.Application.Show.Console.SendMessage("There was a problem removing a cue from the cue stack.", ex)
			End Try
		End Sub

		''' <summary>
		''' Changes the number of a cue.
		''' </summary>
		''' <param name="Cue">The cue to change numbers of.</param>
		''' <param name="Number">The cue's new number.</param>
		''' <remarks></remarks>
		Public Sub ChangeCueNumber(Cue As Cues.CueBase, Number As Double)
			Cue.Number = Number
			CueList.Sort()
			RaisePropertyChanged("CueList")
		End Sub

		''' <summary>
		''' Appropriately updates the status of the Stack Cue, based on the status of the cues within the Stack's CueList.
		''' </summary>
		''' <remarks></remarks>
		Public Sub UpdateStatus()
			If CueList.Where(Function(c) c.Status = CueStatus.Active).Count > 0 Then
				Status = CueStatus.Active
			ElseIf CueList.Where(Function(c) c.Status = CueStatus.Cued AndAlso CueList.IndexOf(c) > 0).Count > 0 Then
				If CueList.IsActive Then
					Status = CueStatus.Active
				Else
					Status = CueStatus.Standby
				End If
			ElseIf CueList.Where(Function(c) c.Status = CueStatus.Cued AndAlso CueList.IndexOf(c) = 0).Count > 0 Then
				Status = CueStatus.Cued
			Else
				Status = CueStatus.Standby
			End If
		End Sub


#End Region

	End Class
End Namespace